import { DgControl } from '../utils/dg-control';
import { GSPElementDataType, GSPElementObjectType } from '@gsp-bef/gsp-cm-metadata';
import { GridFieldDataType, FormSchemaEntityFieldType, DesignerEnvType } from '@farris/designer-services';


/**
 * 提供schema字段和DOM控件属性的映射
 */
export class SchemaDOMMapping {

    /**
     * <字段类型,可配置的控件类型列表>的映射
     */
    static fieldControlTypeMapping = {
        String: [
            { key: DgControl.TextBox.type, value: DgControl.TextBox.name },
            { key: DgControl.LookupEdit.type, value: DgControl.LookupEdit.name },
            { key: DgControl.Image.type, value: DgControl.Image.name },
            { key: DgControl.DateBox.type, value: DgControl.DateBox.name },
            { key: DgControl.TimePicker.type, value: DgControl.TimePicker.name },
            { key: DgControl.CheckGroup.type, value: DgControl.CheckGroup.name },
            { key: DgControl.RadioGroup.type, value: DgControl.RadioGroup.name },
            { key: DgControl.InputGroup.type, value: DgControl.InputGroup.name },
            { key: DgControl.EnumField.type, value: DgControl.EnumField.name },
            { key: DgControl.MultiTextBox.type, value: DgControl.MultiTextBox.name },
            { key: DgControl.RichTextBox.type, value: DgControl.RichTextBox.name },
            { key: DgControl.Tags.type, value: DgControl.Tags.name },
            { key: DgControl.PersonnelSelector.type, value: DgControl.PersonnelSelector.name },
            { key: DgControl.OrganizationSelector.type, value: DgControl.OrganizationSelector.name },
            { key: DgControl.EmployeeSelector.type, value: DgControl.EmployeeSelector.name, supportedEnvType: DesignerEnvType.noCode },
            { key: DgControl.AdminOrganizationSelector.type, value: DgControl.AdminOrganizationSelector.name, supportedEnvType: DesignerEnvType.noCode },
            { key: DgControl.OaRelation.type, value: DgControl.OaRelation.name, supportedEnvType: DesignerEnvType.noCode },
            { key: DgControl.ExtIntergration.type, value: DgControl.ExtIntergration.name, supportedEnvType: DesignerEnvType.noCode }
        ],
        Text: [
            { key: DgControl.MultiTextBox.type, value: DgControl.MultiTextBox.name },
            { key: DgControl.RichTextBox.type, value: DgControl.RichTextBox.name },
            { key: DgControl.Avatar.type, value: DgControl.Avatar.name },
            { key: DgControl.ImageUpload.type, value: DgControl.ImageUpload.name, supportedEnvType: DesignerEnvType.noCode },
            { key: DgControl.LookupEdit.type, value: DgControl.LookupEdit.name }
        ],
        Decimal: [
            { key: DgControl.NumericBox.type, value: DgControl.NumericBox.name }
        ],
        Integer: [
            { key: DgControl.NumericBox.type, value: DgControl.NumericBox.name }
        ],
        Number: [
            { key: DgControl.NumericBox.type, value: DgControl.NumericBox.name }
        ],
        BigNumber: [
            { key: DgControl.NumericBox.type, value: DgControl.NumericBox.name }
        ],
        Date: [
            { key: DgControl.DateBox.type, value: DgControl.DateBox.name }
        ],
        DateTime: [
            { key: DgControl.DateBox.type, value: DgControl.DateBox.name }
        ],
        Boolean: [
            { key: DgControl.SwitchField.type, value: DgControl.SwitchField.name },
            { key: DgControl.CheckBox.type, value: DgControl.CheckBox.name },
        ],
        Enum: [
            { key: DgControl.EnumField.type, value: DgControl.EnumField.name },
            { key: DgControl.RadioGroup.type, value: DgControl.RadioGroup.name },
        ],
        Object: [
            { key: DgControl.LookupEdit.type, value: DgControl.LookupEdit.name },
            { key: DgControl.EnumField.type, value: DgControl.EnumField.name },
            { key: DgControl.RadioGroup.type, value: DgControl.RadioGroup.name },
        ],
        EmployeeSelector: [
            { key: DgControl.EmployeeSelector.type, value: DgControl.EmployeeSelector.name }
        ],
        AdminOrganizationSelector: [
            { key: DgControl.AdminOrganizationSelector.type, value: DgControl.AdminOrganizationSelector.name }
        ]
    };

    /**
     * 提供字段名称和DOM控件标题的映射
     * @param controlType 控件类型
     */
    static getControlName(controlType) {
        let domField = '';
        // 字段名称的映射根据控件类型区分
        switch (controlType) {
            case 'Button': { domField = 'text'; break; }
            case 'GridField': case 'TreeGridField': { domField = 'caption'; break; }
            default: { domField = 'title'; break; }
        }
        return domField;
    }


    /**
     * 提供schema字段基础属性和DOM控件属性的映射
     * @param control 控件元数据
     */
    static mappingDomPropAndSchemaProp(control) {
        const controlType = control.type;
        // 1、 基础字段
        const array = [];

        if (controlType !== DgControl.GridField.type && controlType !== DgControl.TreeGridField.type) {
            array.push({ domField: 'require', schemaField: 'require' });
            array.push({ domField: 'defaultValue', schemaField: 'defaultValue' });
        }

        // 只读属性
        if (controlType !== DgControl.TreeGridField.type) {
            array.push({ domField: 'readonly', schemaField: 'readonly' });
        }

        // 字段名称的映射根据控件类型区分
        switch (controlType) {
            case DgControl.Button.type: { array.push({ domField: 'text', schemaField: 'name' }); break; }
            case DgControl.GridField.type: case DgControl.TreeGridField.type:
                { array.push({ domField: 'caption', schemaField: 'name' }); break; }
            default: { array.push({ domField: 'title', schemaField: 'name' }); }
        }

        // 2、类型字段
        // 文本类型和数字类型映射长度
        if (controlType === DgControl.TextBox.type || controlType === DgControl.MultiTextBox.type
            || controlType === DgControl.NumericBox.type || controlType === DgControl.NumberRange.type) {
            array.push({ domField: 'maxLength', schemaField: 'type.length' });
        }
        // 数字类型映射精度
        if (controlType === DgControl.NumericBox.type || controlType === DgControl.NumberRange.type) {
            array.push({ domField: 'precision', schemaField: 'type.precision' });
        }

        // 枚举类型：下拉控件、表格列控件
        if (controlType === DgControl.EnumField.type || controlType === DgControl.GridField.type ||
            controlType === DgControl.TreeGridField.type || controlType === DgControl.RadioGroup.type) {
            array.push({ domField: 'enumData', schemaField: 'type.enumValues' });
        }

        // 3、编辑器字段
        if (controlType !== DgControl.GridField.type && controlType !== DgControl.TreeGridField.type) {
            array.push({ domField: 'type', schemaField: 'editor.$type' });
        }

        // 日期类型
        if (controlType === DgControl.DateBox.type) {
            array.push({ domField: 'dateFormat', schemaField: 'editor.format' });
            array.push({ domField: 'fieldType', schemaField: 'type.name' });
        }
        // 数字类型、日期类型映射最大、最小值
        if (controlType === DgControl.DateBox.type
            || controlType === DgControl.NumericBox.type || controlType === DgControl.NumberRange.type) {
            array.push({ domField: 'maxValue', schemaField: 'editor.maxValue' });
            array.push({ domField: 'minValue', schemaField: 'editor.minValue' });
        }
        // 帮助类型
        if (controlType === DgControl.LookupEdit.type) {
            array.push({ domField: 'dataSource', schemaField: 'editor.dataSource' });
            array.push({ domField: 'valueField', schemaField: 'editor.valueField' });
            array.push({ domField: 'textField', schemaField: 'editor.textField' });
            array.push({ domField: 'displayType', schemaField: 'editor.displayType' });
            array.push({ domField: 'mapFields', schemaField: 'editor.mapFields' });
            array.push({ domField: 'helpId', schemaField: 'editor.helpId' });

        }
        // 列表多语
        if (controlType === DgControl.GridField.type) {
            array.push({ domField: 'multiLanguage', schemaField: 'multiLanguage' });
        }
        // 列编辑器
        if ((controlType === DgControl.GridField.type || controlType === DgControl.TreeGridField.type) && control.editor) {
            const editorMaps = this.mappingDomPropAndSchemaProp(control.editor);
            editorMaps.map(m => m.domField = 'editor.' + m.domField);
            array.push(...editorMaps);
        }

        // 字段label相关的属性
        array.push({ domField: 'path', schemaField: 'bindingPath' });
        array.push({ domField: 'binding.path', schemaField: 'bindingField' });
        array.push({ domField: 'binding.fullPath', schemaField: 'path' });
        if (controlType === DgControl.GridField.type || controlType === DgControl.TreeGridField.type) {
            array.push({ domField: 'dataField', schemaField: 'bindingPath' });
        }
        return array;
    }


    /**
     * 将字段类型 映射为表单表格列上的类型dataType
     * @param fieldType 字段类型
     */
    static mapMDataType2GridFieldType(fieldType: FormSchemaEntityFieldType): string {
        switch (fieldType.name) {
            case GSPElementDataType.String: case GSPElementDataType.Text: return GridFieldDataType.string;
            case GSPElementDataType.Decimal: case GSPElementDataType.Integer:
            case 'Number': case 'BigNumber': return GridFieldDataType.number;
            case GSPElementDataType.Date: return GridFieldDataType.date;
            case GSPElementDataType.DateTime: return GridFieldDataType.datetime;
            case GSPElementDataType.Boolean: return GridFieldDataType.boolean;
            case GSPElementObjectType.Enum: return GridFieldDataType.enum;
        }

        return '';
    }

    /**
     * 根据字段类型获取可用的控件类型
     * @param fieldType 字段类型
     * @param multiLanguage 是否多语
     * @param cmpType  控件所在的组件类型
     * @param envType  设计器运行环境
     */
    static getEditorTypesByMDataType(fieldType: string, multiLanguage = false, cmpType: string, envType: string): any[] {
        if (multiLanguage) {
            return [{ key: DgControl.LanguageTextBox.type, value: '多语言输入框' }];
        }
        let editorTypeIterator = this.fieldControlTypeMapping[fieldType];

        // 列表列编辑器支持的控件类型有限
        if (cmpType === 'dataGrid' && editorTypeIterator) {
            const notAllowedType = [
                DgControl.CheckGroup.type, DgControl.RadioGroup.type, DgControl.RichTextBox.type,
                DgControl.Image.type, DgControl.Tags.type, DgControl.Avatar.type];
            editorTypeIterator = editorTypeIterator.filter(ele => !notAllowedType.includes(ele.key));
        }

        // 某些控件只在特定环境下展示，例如外部服务只在零代码环境上才显示
        editorTypeIterator = editorTypeIterator.filter(ele => !ele.supportedEnvType || ele.supportedEnvType === envType);

        return editorTypeIterator || [];
    }



    /**
     * 根据变量类型获取控件编辑器类型
     */
    static getEditorTypeByVariableType(type: string) {
        switch (type) {
            case GSPElementDataType.String: {
                return DgControl.TextBox.type;
            }
            case 'Number': {
                return DgControl.NumericBox.type;
            }
            case GSPElementDataType.Boolean: {
                return DgControl.CheckBox.type;
            }
            case GSPElementDataType.Date: case GSPElementDataType.DateTime: {
                return DgControl.DateBox.type;
            }
            case GSPElementDataType.Text: {
                return DgControl.MultiTextBox.type;
            }
        }
    }
}
